﻿using blackhouse.WebNemo.Business.Groups;
using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Web;

namespace blackhouse.WebNemo.Web {
    public class HostRecordFileOperation : RecordFileOperation {

        #region Fields

        private readonly NemoRecordFileOperation nemoFileOperation;
        private readonly string fileLocations = String.Empty;

        #endregion

        #region Constructors

        public HostRecordFileOperation(int groupId, string column, int recordId)
            : base(groupId, column, recordId) {
            this.nemoFileOperation = new NemoRecordFileOperation(groupId, column, recordId);
            this.fileLocations = GetFileLocations();
            if (!this.fileLocations.EndsWith(@"\"))
                this.fileLocations = this.fileLocations + @"\";
            this.fileLocations = this.SpecificFileLocations(this.fileLocations);
        }

        #endregion

        #region Methods

        private string SpecificFileLocations(string parentLocation) {
            var specFileLocations = parentLocation + this.RecordId + "_" + this.Column + @"\";
            var sdi = new DirectoryInfo(specFileLocations);
            if (!sdi.Exists)
                sdi.Create();
            return specFileLocations;
        }

        private static string GetFileLocations() {
            var location = ConfigurationManager.AppSettings["NemoHostFileLocation"];
            if (!String.IsNullOrEmpty(location)) {
                var di = new DirectoryInfo(location);
                if (di.Exists)
                    return location;
            }
            location = HttpContext.Current.Server.MapPath("~/Nemo/HostFiles");
            var dil = new DirectoryInfo(location);
            if (!dil.Exists)
                dil.Create();
            return dil.FullName;
        }

        public override bool SaveFile(RecordFileData fileData, Stream fileStream) {
            var extension = fileData.FileName.Split('.').Last();
            var fi = new FileInfo(this.fileLocations + this.RecordId + '.' + extension);
            if (fi.Exists)
                fi.Delete();
            if (fileStream != null) {
                using (var fs = fi.Create()) {
                    if (fileStream.CanSeek)
                        fileStream.Seek(0, SeekOrigin.Begin);
                    fileStream.CopyTo(fs);
                }
            }
            using (var ss = this.GenerateStreamFromString(fi.FullName)) {
                this.nemoFileOperation.SaveFile(fileData, ss);
            }
            return true;
        }

        public Stream GenerateStreamFromString(string s) {
            var stream = new MemoryStream();
            var writer = new StreamWriter(stream);
            writer.Write(s);
            writer.Flush();
            stream.Position = 0;
            return stream;
        }

        public override byte[] GetFileData() {
            var di = new DirectoryInfo(this.fileLocations);
            var fis = di.GetFiles(this.RecordId + ".*");
            if (fis.Length != 1) return null;
            byte[] data;
            var fi = fis[0];
            using (var fs = fi.OpenRead()) {
                data = this.ReadFully(fs);
            }
            return data;
        }

        public byte[] ReadFully(Stream input) {
            var buffer = new byte[16 * 1024];
            using (var ms = new MemoryStream()) {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0) {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }

        public override RecordFileData GetInfo() {
            return this.nemoFileOperation.GetInfo();
        }

        public static void CopyFilesFromDatabaseToHost(GroupRecords records, string column) {
            foreach (var record in records) {
                CopyFileFromDatabaseToHost(record.BelongsToGroupId, column, record.RecordId);
            }
        }

        private static void CopyFileFromDatabaseToHost(int groupId, string column, int recordId) {
            var nfo = new NemoRecordFileOperation(groupId, column, recordId);
            var hfo = new HostRecordFileOperation(groupId, column, recordId);
            if (!nfo.GetInfo().Exist) return;
            using (var ms = new MemoryStream(nfo.GetFileData())) {
                hfo.SaveFile(nfo.GetInfo(), ms);
            }
        }

        #endregion

    }
}
